有一個東西不受資料型別的限制,還能讓同一個函式收到不同型別傳來的值。
他是誰?
Interface
是一個定義一組方法的命名型態,任何類型只要實現了這些方法,就被視為實現了該 Interface
。這使得不同的類型可以用相同的方式進行操作。
假設你在一個火車站,有不同種類的火車(不同類型的對象)像是自強號、莒光號、...要進站(被用在某個程式碼中)。
火車站有統一的 月台
,我們將月台想像成 Interface
,每種火車都需要停在這個月台上,並且必須具備某些基本特徵,例如:能夠開車、停車、回報目的與狀況...等。這個月台定義了所有火車 共享
的操作,但不關心具體火車的型號。
舉例:
package main
import "fmt"
// 定義一個月台 (interface)
type TrainPlatform interface {
StartRunning()
StopRunning()
ReportDestination(string)
}
// 定義區間車的結構
type RegularTrain struct {
Name string
}
//
func (t RegularTrain) StartRunning() {
fmt.Printf("%s 開車!\n", t.Name)
}
//
func (t RegularTrain) StopRunning() {
fmt.Printf("%s 停車 !\n", t.Name)
}
// 報告目的
func (t RegularTrain) ReportDestination(destination string) {
fmt.Printf("%s 即將到站 %s!\n", t.Name, destination)
}
func main() {
trainA := RegularTrain{Name: "區間特快"}
trainA.StartRunning()
trainA.ReportDestination("彰化")
trainA.StopRunning()
}
區間特快 開車!
區間特快 即將到站 彰化!
區間特快 停車 !
有一個溫度,以攝氏度表示,但你需要將其轉換為華氏度。這是一個常見的數據轉換。攝氏度到華氏度的轉換公式如下:
華氏度 = (攝氏度 × 9/5) + 32
package main
import "fmt"
func main() {
celsius := 25.0 // 攝氏度
fahrenheit := (celsius * 9 / 5) + 32 // 轉換為華氏度
fmt.Printf("攝氏 %.2f 度 = 華氏 %.2f 度\n", celsius, fahrenheit)
}
攝氏 25.00 度 = 華氏 77.00 度
Interface Conversions
將一個實現了某介面的具體類型轉換為該介面的操作。
舉例:
有一台電腦主機,主機有多個 USB 接口可以接受 不同種類
的USB 設備,例如 USB 滑鼠、USB 鍵盤、USB 影印機...等等。
這裡的USB接口就可以被視為一個 interface
,它定義了一組標準方法(例如數據傳輸、電源供應等等),這些方法可以被不同種類的 USB 設備連接。
舉例:
package main
import "fmt"
// 定義 USB 設備 interface
type USBDevice interface {
Connect()
Disconnect()
}
// 定義 USB 滑鼠
type USBMouse struct {
Name string
}
func (m USBMouse) Connect() {
fmt.Printf("%s 滑鼠已連線。\n", m.Name)
}
func (m USBMouse) Disconnect() {
fmt.Printf("%s 滑鼠離開連線\n", m.Name)
}
// 定義 USB 鍵盤
type USBKeyboard struct {
Name string
}
func (k USBKeyboard) Connect() {
fmt.Printf("%s 鍵盤已連線\n", k.Name)
}
func (k USBKeyboard) Disconnect() {
fmt.Printf("%s 鍵盤離開連線\n", k.Name)
}
func main() {
mouse := USBMouse{Name: "Logitech"}
keyboard := USBKeyboard{Name: "Dell"}
devices := []USBDevice{mouse, keyboard}
for _, device := range devices {
device.Connect()
device.Disconnect()
}
}
Logitech 滑鼠已連線。
Logitech 滑鼠離開連線
Dell 鍵盤已連線
Dell 鍵盤離開連線
Type Assertions
用於檢查介面值的 實際存儲類型
,並將其轉換為該具體類型。
package main
import "fmt"
// 定義一個介面叫做Shape
type Shape interface {
Area() float64
}
// 定義一個矩形結構
type Rectangle struct {
Width float64
Height float64
}
// 實現Shape介面的Area方法
func (r Rectangle) Area() float64 {
return r.Width * r.Height
}
func main() {
rectangle := Rectangle{Width: 5, Height: 3}
// 將Rectangle實例轉換為Shape介面
var shape Shape
shape = rectangle
// 使用 Type Assertions 檢查介面值的實際類型並取得具體類型的值
if r, ok := shape.(Rectangle); ok {
fmt.Printf("矩形的寬度:%f\n", r.Width)
} else {
fmt.Println("這不是一個矩形。")
}
}
矩形的寬度:5.000000
Generality
指的是 Interface
提供的方式用来描述對象的行為,而不考慮型別。這允許不同型別的對應相同的 Interface
,可以用一致的方式進行操作和處理。
舉例:
package main
import "fmt"
// 定義一個通用的 Shape interface
type Shape interface {
Area() float64
}
// 定義一個矩形結構體
type Rectangle struct {
Width float64
Height float64
}
func (r Rectangle) Area() float64 {
return r.Width * r.Height
}
type Circle struct {
Radius float64
}
func (c Circle) Area() float64 {
return 3.14 * c.Radius * c.Radius
}
func main() {
rectangle := Rectangle{Width: 5, Height: 3}
circle := Circle{Radius: 2}
// 使用通用的 Shape interface 来計算面積
shapes := []Shape{rectangle, circle}
for _, shape := range shapes {
area := shape.Area()
fmt.Printf("面積:%f\n", area)
}
}
面積:15.000000
面積:12.560000
Interface
為我們提供了一種通用的方式來描述不同對象的行為,就像 Platform 9¾ 為麻瓜們提供了通往霍格華茲的道路一樣。
(都入秋了為什麼還這麼熱!